﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace Icedream.InstantFileTransfer
{
    /// <summary>
    /// Represents a plugin base to implement compression algorithms
    /// </summary>
    public class IFTPStreamPlugin
    {
        /// <summary>
        /// Inidicates the string which is send as an argument to the server's FILE response.
        /// Must be something other than NULL and "".
        /// </summary>
        public string CompressionString = null;

        /// <summary>
        /// The name of the compression plugin. It is used in LoadedCompressionModules in IFTPClient and IFTPServer.
        /// If this is NULL, the CompressionString is used instead.
        /// </summary>
        public string CompressionName = null;

        /// <summary>
        /// Tells the client or the server if this plugin is able of compressing a stream.
        /// </summary>
        public bool CanCompress = false;

        /// <summary>
        /// Tells the client or the server if this plugin is able of decompressing a stream.
        /// </summary>
        public bool CanDecompress = false;

        /// <summary>
        /// This is a void to override to do the stream decompression.
        /// </summary>
        /// <param name="fileStream">The local file in which to save the decoded data.</param>
        /// <param name="networkStream">The network stream from which the compressed data is read.</param>
        /// <param name="bufferSize">The buffer size used for transferring in bytes. Usually 4096.</param>
        /// <returns>False if transfer has been aborted, otherwise True</returns>
        public virtual bool Decompress(NetworkStream networkStream, FileStream fileStream, int bufferSize, string fileCode, long totalBytes)
        {
            throw new NotImplementedException("Plugin did not implement Decompress()");
        }

        /// <summary>
        /// This is a void to override to do the stream compression.
        /// </summary>
        /// <param name="fileStream">The local file from which to read the raw data.</param>
        /// <param name="networkStream">The network stream to which the compressed data is sent.</param>
        /// <param name="bufferSize">The buffer size used for transferring in bytes. Usually 4096.</param>
        /// <returns>False if transfer has been aborted, otherwise True</returns>
        public virtual bool Compress(FileStream fileStream, NetworkStream networkStream, int bufferSize, string fileCode)
        {
            throw new NotImplementedException("Plugin did not implement Compress()");
        }

        /// <summary>
        /// Use this to report the current progress.
        /// </summary>
        /// <param name="decodedBytes">This you should fill with the actual amount of decoded bytes.</param>
        private void ReportProgress(string filecode, long bytesDecoded, long bytesTotal, out bool cancel)
        {
            if (ReportProgressEvent != null)
                ReportProgressEvent(filecode, bytesDecoded, bytesTotal, out cancel);
            else
                cancel = false;
        }

        /// <summary>
        /// This is set by the server or the client. Plugins use ReportProgress() instead.
        /// </summary>
        public event FileProgressDelegate ReportProgressEvent;
    }
}
